package pt.iscte.pidesco.filebrowser.internal;

import java.io.File;
import java.util.Map;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;

import pt.iscte.pidesco.extensibility.IscdeComponent;
import pt.iscte.pidesco.filebrowser.model.ClassElement;
import pt.iscte.pidesco.filebrowser.model.PackageElement;
import pt.iscte.pidesco.filebrowser.model.SourceElement;
import pt.iscte.pidesco.filebrowser.service.SourceTreeListener;

public class ProjectBrowser implements IscdeComponent {

	private TreeViewer viewer;
	private Action action1;

	private PackageElement invisibleRoot;

	private Image packageIcon;
	private Image classIcon;

	@Override
	public void createContents(Composite viewArea, Map<String, Image> images) {
		packageIcon = images.get("package.gif");
		classIcon = images.get("class.gif");
		viewer = new TreeViewer(viewArea, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
		viewer.setContentProvider(new ViewContentProvider());
		viewer.setLabelProvider(new ViewLabelProvider());
		viewer.setSorter(new NameSorter());

		File srcRoot = new File("/Users/andresantos/Desktop/workspace-pa2014/WarmUpWeek/src");
		invisibleRoot = scan(srcRoot);


		viewer.setInput(invisibleRoot);



		makeActions();
		hookContextMenu();
		hookDoubleClickAction();
		//		contributeToActionBars();
	}




	static class ViewContentProvider implements IStructuredContentProvider, ITreeContentProvider {

		private static final Object[] EMPTY = new Object[0];
		
		public void inputChanged(Viewer v, Object oldInput, Object newInput) {

		}

		public void dispose() {

		}

		public Object[] getElements(Object parent) {
			return getChildren(parent);

		}

		public Object getParent(Object child) {
			return ((SourceElement)child).getParent();
		}

		public Object[] getChildren(Object parent) {
			if (parent instanceof PackageElement)
				return ((PackageElement)parent).getChildren().toArray();
			else
				return EMPTY;
		}

		public boolean hasChildren(Object parent) {
			return parent instanceof PackageElement && ((PackageElement)parent).hasChildren();
		}

	}

	private static Filter NO_FILTER = new Filter() {
		@Override
		public boolean accept(File file) {
			return true;
		}
	};

	private static PackageElement scan(File root) {
		PackageElement pack = new PackageElement(null, "");
		for(File child : root.listFiles()) {
			scanRec(child, pack, NO_FILTER);
		}
		return pack;
	}

	private static void scanRec(File f, PackageElement p, Filter filter) {
		if(f.isFile() && f.getName().endsWith(".java") && filter.accept(f)) {
			new ClassElement(p, f);
		}
		else if(f.isDirectory()) {
			PackageElement childPack = new PackageElement(p, f.getName());
			for(File child : f.listFiles()) {
				scanRec(child, childPack, filter);
			}
		}
	}

	//	private static Collection<String> scan(File root, Filter filter) {
	//		Collection<String> paths = new ArrayList<String>();
	//		scanRec(root, paths, filter);
	//		return paths;
	//	}

	class ViewLabelProvider extends LabelProvider {

		public String getText(Object obj) {
			return obj.toString();
		}
		public Image getImage(Object obj) {
			return ((SourceElement) obj).isPackage() ? packageIcon : classIcon;
		}
	}
	
	class NameSorter extends ViewerSorter {

	}


	private void hookContextMenu() {
		MenuManager menuMgr = new MenuManager("#PopupMenu");
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {
				//				SourceBrowser.this.fillContextMenu(manager);
			}
		});
		Menu menu = menuMgr.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);
		//		getSite().registerContextMenu(menuMgr, viewer);
	}

	//	private void contributeToActionBars() {
	//		IActionBars bars = getViewSite().getActionBars();
	//		fillLocalPullDown(bars.getMenuManager());
	//		fillLocalToolBar(bars.getToolBarManager());
	//	}

	private void fillLocalPullDown(IMenuManager manager) {
		manager.add(action1);
		manager.add(new Separator());
	}

	//	private void fillContextMenu(IMenuManager manager) {
	//		manager.add(action1);
	//		manager.add(new Separator());
	//		drillDownAdapter.addNavigationActions(manager);
	//		// Other plug-ins can contribute there actions here
	//		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	//	}

	//	private void fillLocalToolBar(IToolBarManager manager) {
	//		manager.add(action1);
	//		manager.add(new Separator());
	//		drillDownAdapter.addNavigationActions(manager);
	//	}

	private void makeActions() {
		action1 = new Action() {
			public void run() {
				File fileToOpen = new File("/Users/andresantos/Desktop/IP_Workspace/Semana1/Functions.java");

				if (fileToOpen.exists() && fileToOpen.isFile()) {
					IFileStore fileStore = EFS.getLocalFileSystem().getStore(fileToOpen.toURI());
					IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();

					try {
						IDE.openEditorOnFileStore( page, fileStore );
					} catch ( PartInitException e ) {
						//Put your exception handler here if you wish to
					}
				} else {
					//Do something if the file does not exist
				}
			}
		};
		action1.setText("Action 1");
		action1.setToolTipText("Action 1 tooltip");
		action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
				getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));



	}

	private void hookDoubleClickAction() {
		viewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				IStructuredSelection s = (IStructuredSelection) viewer.getSelection();
				if(s.size() == 1) {
					SourceElement e = (SourceElement) s.getFirstElement();
					for(SourceTreeListener l : Activator.getInstance().getListeners()) {
						l.doubleClick(e);
					}
				}
			}
		});
	}
	
	private void showMessage(String message) {
		MessageDialog.openInformation(
				viewer.getControl().getShell(),
				"Sample View",
				message);
	}

//	@Override
//	public String getViewTitle() {
//		return "Source Browser";
//	}

//	@Override
//	public String getViewTitleTooltip() {
//		return "my tool tip";
//	}

//	@Override
//	public Image getTitleIcon() {
//		// TODO Auto-generated method stub
//		return null;
//	}

}
